home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 7
/
Apprentice-Release7.iso
/
Source Code
/
Pascal
/
Snippets
/
Demo
/
GraySlider.p
< prev
next >
Wrap
Text File
|
1997-07-22
|
6KB
|
222 lines
UNIT GraySlider;
INTERFACE
USES
Types, QuickDraw, Icons, OffscreenUtils;
CONST
kSliderBorder = 8; { Space left between indicator and border of body }
TYPE
SliderAxis = (axHoricontal, axVertical);
SliderActionProc = PROCEDURE (minimum, maximum, value: INTEGER);
TYPE
GraySliderInfo = RECORD
axis: SliderAxis;
bodyRect: Rect;
bodyPict: PicHandle;
indicatorIcon, selectedIndicatorIcon: CIconHandle;
minimum, maximum, value: INTEGER;
offscreen: OffscreenAreaPtr;
END;
PROCEDURE InitializeGraySlider(axis: SliderAxis; bodyRect: Rect; bodyPictID: INTEGER; indicatorCicnID, selectedIndicatorCicnID: INTEGER; minimum, maximum, value: INTEGER; VAR info: GraySliderInfo);
PROCEDURE DrawGraySlider(info: GraySliderInfo);
PROCEDURE FreeGraySlider(info: GraySliderInfo);
FUNCTION HitGraySlider(info: GraySliderInfo; pt: Point): BOOLEAN;
FUNCTION TrackGraySlider(VAR info: GraySliderInfo; action: SliderActionProc): BOOLEAN;
IMPLEMENTATION
USES
Events;
PROCEDURE InitializeGraySlider(axis: SliderAxis; bodyRect: Rect; bodyPictID: INTEGER; indicatorCicnID, selectedIndicatorCicnID: INTEGER; minimum, maximum, value: INTEGER; VAR info: GraySliderInfo);
VAR
box: Rect;
indicatorSize, bodyCenter: INTEGER;
BEGIN
info.axis := axis;
info.bodyRect := bodyRect;
info.bodyPict := GetPicture(bodyPictID);
info.indicatorIcon := GetCIcon(indicatorCicnID);
info.selectedIndicatorIcon := GetCIcon(selectedIndicatorCicnID);
info.minimum := minimum;
info.maximum := maximum;
info.value := value;
IF axis = axHoricontal THEN
BEGIN
indicatorSize := info.indicatorIcon^^.iconPMap.bounds.right + 1;
bodyCenter := bodyRect.top + (bodyRect.bottom - bodyRect.top) DIV 2;
box := bodyRect;
box.top := bodyCenter - indicatorSize DIV 2 - 1;
box.bottom := bodyCenter + indicatorSize DIV 2 + 1;
END
ELSE
BEGIN
indicatorSize := info.indicatorIcon^^.iconPMap.bounds.bottom + 1;
bodyCenter := bodyRect.left + (bodyRect.right - bodyRect.left) DIV 2;
box := bodyRect;
box.left := bodyCenter - indicatorSize DIV 2 - 1;
box.right := bodyCenter + indicatorSize DIV 2 + 1;
END;
AllocateOffscreenArea(box, info.offscreen);
IF info.offscreen = NIL THEN
DebugStr('InitializeGraySlider: AllocateOffscreenArea');
END;
PROCEDURE FreeGraySlider(info: GraySliderInfo);
BEGIN
FreeOffscreenArea(info.offscreen);
END;
FUNCTION PtToValue(info: GraySliderInfo; pt: Point): INTEGER;
VAR
width, height, range: INTEGER;
BEGIN
range := info.maximum - info.minimum;
IF info.axis = axHoricontal THEN
BEGIN
width := info.bodyRect.right - info.bodyRect.left - 2 * kSliderBorder;
pt.h := pt.h - (info.bodyRect.left + kSliderBorder);
IF pt.h < 0 THEN
PtToValue := info.minimum
ELSE IF pt.h > width THEN
PtToValue := info.maximum
ELSE
PtToValue := pt.h * range DIV width + info.minimum;
END
ELSE
BEGIN
height := info.bodyRect.bottom - info.bodyRect.top - 2 * kSliderBorder;
pt.v := pt.v - (info.bodyRect.top + kSliderBorder);
IF pt.v < 0 THEN
PtToValue := info.minimum
ELSE IF pt.v > height THEN
PtToValue := info.maximum
ELSE
PtToValue := pt.v * range DIV height + info.minimum;
END;
END;
FUNCTION ValueToPt(info: GraySliderInfo): Point;
VAR
value, range: INTEGER;
width, height: INTEGER;
pt: Point;
BEGIN
value := info.value - info.minimum;
range := info.maximum - info.minimum;
width := info.bodyRect.right - info.bodyRect.left;
height := info.bodyRect.bottom - info.bodyRect.top;
IF info.axis = axHoricontal THEN
BEGIN
width := width - 2 * kSliderBorder;
pt.v := info.bodyRect.top + height DIV 2;
pt.h := info.bodyRect.left + kSliderBorder + value * width DIV range;
END
ELSE
BEGIN
height := height - 2 * kSliderBorder;
pt.h := info.bodyRect.left + width DIV 2;
pt.v := info.bodyRect.top + kSliderBorder + value * width DIV range;
END;
ValueToPt := pt;
END;
PROCEDURE CenterRectAroundPoint(r1: Rect; pt: Point; VAR r2: Rect);
VAR
width, height: INTEGER;
BEGIN
width := r1.right - r1.left;
height := r1.bottom - r1.top;
r2.left := pt.h - width DIV 2;
r2.top := pt.v - height DIV 2;
r2.right := r2.left + width;
r2.bottom := r2.top + height;
END;
FUNCTION CalculateIndicatorRect(info: GraySliderInfo): Rect;
VAR
r: Rect;
BEGIN
CenterRectAroundPoint(info.indicatorIcon^^.iconPMap.bounds, ValueToPt(info), r);
CalculateIndicatorRect := r;
END;
PROCEDURE DrawGraySlider(info: GraySliderInfo);
VAR
r: Rect;
BEGIN
StartDrawingOffscreen(info.offscreen);
DrawPicture(info.bodyPict, info.bodyRect);
r := CalculateIndicatorRect(info);
PlotCIcon(r, info.indicatorIcon);
CopyOffscreenToScreen(info.offscreen);
END;
FUNCTION HitGraySlider(info: GraySliderInfo; pt: Point): BOOLEAN;
VAR
box: Rect;
BEGIN
box := CalculateIndicatorRect(info);
HitGraySlider := PtInRect(pt, box) OR PtInRect(pt, info.bodyRect);
END;
FUNCTION TrackGraySlider(VAR info: GraySliderInfo; action: SliderActionProc): BOOLEAN;
VAR
pt: Point;
r: Rect;
value: INTEGER;
BEGIN
r := CalculateIndicatorRect(info);
PlotCIcon(r, info.selectedIndicatorIcon);
WHILE Button DO
BEGIN
GetMouse(pt);
value := PtToValue(info, pt);
IF value <> info.value THEN
BEGIN
StartDrawingOffscreen(info.offscreen);
EraseRect(CalculateIndicatorRect(info));
info.value := value;
DrawPicture(info.bodyPict, info.bodyRect);
r := CalculateIndicatorRect(info);
PlotCIcon(r, info.selectedIndicatorIcon);
CopyOffscreenToScreen(info.offscreen);
IF action <> NIL THEN
action(info.minimum, info.maximum, info.value);
END;
END;
r := CalculateIndicatorRect(info);
PlotCIcon(r, info.indicatorIcon);
TrackGraySlider := TRUE;
END;
END.